﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace SalePromotion.Pagination
{
    public sealed class PagedList<T> : IPagedList<T>
    {
        private readonly IEnumerable<T> _source;
        private readonly long _totalItems;
        private readonly int _totalPages;
        private readonly PaginationOptions _pagination;

        public PagedList(IEnumerable<T> source, long totalItems, PaginationOptions pagination)
        {
            _pagination = pagination;
            _totalItems = totalItems;
            _source = source;
            _totalPages = CalculateTotalPages();
        }

        public IEnumerable<T> Items
        {
            get { return _source; }
        }

        public IEnumerable<int> Pages
        {
            get
            {
                for (var page = 1; page <= TotalPages; page++)
                {
                    yield return page;
                }
            }
        }

        public int ItemsPerPage
        {
            get { return _pagination.ItemsPerPage; }
        }

        /// <summary>
        /// Index of the current page, starting at 1
        /// </summary>
        public int CurrentPage
        {
            get { return _pagination.CurrentPage; }
        }

        public int PreviousPage
        {
            get { return Math.Max(0, CurrentPage - 1); }
        }

        public int NextPage
        {
            get { return Math.Min(TotalPages, CurrentPage + 1); }
        }

        public bool IsFirstPage
        {
            get { return CurrentPage == 1; }
        }

        public bool IsLastPage
        {
            get { return CurrentPage == TotalPages; }
        }

        public long TotalItems
        {
            get { return _totalItems; }
        }

        public int TotalPages
        {
            get { return _totalPages; }
        }

        private int CalculateTotalPages()
        {
            if (_totalItems == 0) return 0;

            var pages = _totalItems / _pagination.ItemsPerPage;
            var total = (_totalItems % _pagination.ItemsPerPage == 0) ? pages : pages + 1;
            return (int) total;
        }

        #region Implementation of IEnumerable

        public IEnumerator<T> GetEnumerator()
        {
            return _source.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}